package com.darwin.darwinNet
{
	import com.adobe.serialization.json.JSON;
	import com.darwin.darwinNet.events.NetErrorEvent;
	import com.darwin.darwinNet.events.NetEvent;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.TimerEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.Timer;

	/**
	 * Http请求类 
	 * @author vanCopper
	 * 
	 */	
	public class FHttp extends EventDispatcher
	{
		private var _timeout:int = 30;
		
		/**
		 * 保存已发送命令等待时间 
		 */		
		private var _cmdDic:Dictionary = new Dictionary();
		
		private var _timer:Timer;
		
		public function FHttp()
		{
			_timer = new Timer(1000);
			_timer.addEventListener(TimerEvent.TIMER,onTimer);
		}
		
		private function onTimer(e:TimerEvent):void
		{
			for (var cmd:String in _cmdDic) 
			{
				_cmdDic[cmd] += 1;
				if(_cmdDic[cmd] >= timeout)
				{
					var netErrorEvent:NetErrorEvent = new NetErrorEvent(NetErrorEvent.TIMEOUT_ERROR);
					netErrorEvent.cmd = cmd;
					dispatchEvent(netErrorEvent);
					delete _cmdDic[cmd];
				}
			}
			
		}
		
		/**
		 * 发送网络请求 
		 * @param cmd
		 * @param data
		 * @param url
		 * @param other
		 * @param method post/get
		 * 
		 */		
		public function send(cmd:String,data:Object,url:String,other:Object = null,method:String = "post"):void
		{
			if(!_timer.running)
			{
				_timer.start();
			}
			
			var postUrl:String = url + cmd;
			_cmdDic[cmd] = 0;
			var urlRequest:URLRequest;
			if(method == "post")
			{
				urlRequest = HttpRequest.getPostRequest(postUrl);
			}else
			{
				urlRequest = HttpRequest.getGetRequest(postUrl);
			}
			var postData:String = com.adobe.serialization.json.JSON.encode(data);
			var reqVar:URLVariables = new URLVariables();
			reqVar.data = postData;
			urlRequest.data = reqVar;
			var urlLoader:URLLoader = new URLLoader();
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
			urlLoader.addEventListener(Event.COMPLETE,onComplete);
			urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS,onStatus);
			urlLoader.addEventListener(ProgressEvent.PROGRESS,onProgress);
			urlLoader.load(urlRequest);
		}
		
		/**
		 * 发送文件流 
		 * @param cmd
		 * @param fileData
		 * @param url
		 * @param fileName
		 * 
		 */		
		public function sendFile(cmd:String,fileData:ByteArray,url:String,fileName:String = ""):void
		{
			var postUrl:String = url + cmd;
			var urlRequest:URLRequest = HttpRequest.getFileRequest(postUrl);
			//文件格式: 前4个字节为后面文件名的长度  文件名（长度由文件头决定） 剩余部分为文件数据
			
			var byteArray:ByteArray = new ByteArray();
			if(fileName != "")
			{
				var fileNameLen:int = fileName.length*2;
				byteArray.writeUnsignedInt(fileNameLen);
				byteArray.writeUTFBytes(fileName);
				byteArray.writeBytes(fileData);
			}
			
			urlRequest.data = byteArray;
			
			var urlLoader:URLLoader = new URLLoader();
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
			urlLoader.addEventListener(Event.COMPLETE,onComplete);
			urlLoader.load(urlRequest);
		}
		
		/**
		 * 网络请求进度 
		 * @param event
		 * 
		 */		
		protected function onProgress(event:ProgressEvent):void
		{
			var urlLoader:URLLoader = event.currentTarget as URLLoader;
			urlLoader.removeEventListener(ProgressEvent.PROGRESS,onProgress);
		}
		
		/**
		 * 请求返回状态码 
		 * @param event
		 * 
		 */		
		protected function onStatus(event:HTTPStatusEvent):void
		{
			var urlLoader:URLLoader = event.currentTarget as URLLoader;
			urlLoader.removeEventListener(HTTPStatusEvent.HTTP_STATUS,onStatus);
		}
		
		/**
		 * 网络请求完成 
		 * @param event
		 * 
		 */		
		protected function onComplete(event:Event):void
		{
			var urlLoader:URLLoader = event.currentTarget as URLLoader;
			urlLoader.removeEventListener(Event.COMPLETE,onComplete);
			
			var result:String = event.currentTarget.data;
			var r1:RegExp = /([^\w^\"])(\d{18,})([^\w^\"])/g;
			result = result.replace(r1,"$1\"$2\"$3");
			if(result=="")return;
			var data:Object = com.adobe.serialization.json.JSON.decode(result);
			if(data && data.hasOwnProperty("method"))
			{
				var method:String = data["method"];
				if(_cmdDic[method])
				{
					delete _cmdDic[method];
				}
			}
			var completeEvent:NetEvent = new NetEvent(NetEvent.NET_COMPLETE,data);
			dispatchEvent(completeEvent);
		}
		
		/**
		 * 网络请求流错误 
		 * @param event
		 * 
		 */		
		protected function onIOError(event:IOErrorEvent):void
		{
			var urlLoader:URLLoader = event.currentTarget as URLLoader;
			urlLoader.removeEventListener(IOErrorEvent.IO_ERROR,onIOError);
			
			var ioErrorEvent:NetErrorEvent = new NetErrorEvent(NetErrorEvent.NET_IOERROR);
			dispatchEvent(ioErrorEvent);
		}

		/**
		 * 命令超时时间间隔 
		 */
		public function get timeout():int
		{
			return _timeout;
		}

		/**
		 * @private
		 */
		public function set timeout(value:int):void
		{
			_timeout = value;
		}

		
	}
}